#region License
// Copyright (c) 2007 James Newton-King
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
#endregion

using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;
using Newtonsoft.Utilities.Miscellaneous;
using System.Globalization;
using System.Data.SqlTypes;
using Newtonsoft.Utilities.Testing;

namespace Newtonsoft.Utilities.Tests.Miscellaneous
{
  public class ConvertUtilsTests : TestsBase
  {
    #region Convert
    [Test]
    public void ConvertToInt32()
    {
      int i;

      i = ConvertUtils.Convert<int>("5");
      Assert.AreEqual(5, i);

      i = ConvertUtils.Convert<int>(9.1);
      Assert.AreEqual(9, i);

      i = ConvertUtils.Convert<int>(9.5);
      Assert.AreEqual(10, i);

      i = ConvertUtils.Convert<int>(9.9999999999999999);
      Assert.AreEqual(10, i);

    }

    [Test]
    public void ConvertToObject()
    {
      object o;

      o = ConvertUtils.Convert<object>(new object());
      Assert.IsNotNull(o);
    }

    [Test]
    public void ConvertToNullableInt32()
    {
      int? i;

      i = ConvertUtils.Convert<int?>(string.Empty);
      Assert.AreEqual(null, i);

      i = ConvertUtils.Convert<int?>(DBNull.Value);
      Assert.AreEqual(null, i);

      i = ConvertUtils.Convert<int?>(SqlInt32.Null);
      Assert.AreEqual(null, i);
    }

    [Test]
    public void ConvertToString()
    {
      string s;

      s = ConvertUtils.Convert<string>(new DateTime(2000, 12, 12, 12, 12, 12), CultureInfo.InvariantCulture);

      Assert.AreEqual("12/12/2000 12:12:12", s);

      s = ConvertUtils.Convert<string>(string.Empty);

      Assert.AreEqual(string.Empty, s);

      s = ConvertUtils.Convert<string>(typeof(Version));

      Assert.AreEqual("System.Version", s);
    }

    [Test]
    [ExpectedException(typeof(ArgumentException), ExpectedMessage = @"Target type System.IComparable is not a value type or a non-abstract class.
Parameter name: targetType")]
    public void ConvertToInterface()
    {
      ConvertUtils.Convert<IComparable>(string.Empty);
    }
    #endregion

    #region TryConvert
    [Test]
    public void TryConvertInt32()
    {
      int convertedValue;
      Assert.IsFalse(ConvertUtils.TryConvert<int>(string.Empty, out convertedValue));
      Assert.AreEqual(0, convertedValue);

      Assert.IsFalse(ConvertUtils.TryConvert<int>(DateTime.Now, out convertedValue));
      Assert.AreEqual(0, convertedValue);

      Assert.IsFalse(ConvertUtils.TryConvert<int>(null, out convertedValue));
      Assert.AreEqual(0, convertedValue);

      Assert.IsTrue(ConvertUtils.TryConvert<int>("9999", out convertedValue));
      Assert.AreEqual(9999, convertedValue);

      Assert.IsTrue(ConvertUtils.TryConvert<int>(new SqlInt32(-1), out convertedValue));
      Assert.AreEqual(-1, convertedValue);

      Assert.IsFalse(ConvertUtils.TryConvert<int>(SqlInt32.Null, out convertedValue));
      Assert.AreEqual(0, convertedValue);
    }
    #endregion

    #region ConvertOrCast
    [Test]
    [ExpectedException(typeof(Exception), ExpectedMessage = "Could not cast or convert from System.Object to System.IComparable.")]
    public void ConvertOrCastObjectToIComparable()
    {
      ConvertUtils.ConvertOrCast<IComparable>(new object());
    }

    [Test]
    public void ConvertOrCastNull()
    {
      Assert.IsNull(ConvertUtils.ConvertOrCast<IComparable>(null));

      Assert.IsNull(ConvertUtils.ConvertOrCast<int?>(null));

      Assert.IsNull(ConvertUtils.ConvertOrCast<object>(null));

      Assert.IsNull(ConvertUtils.ConvertOrCast<string>(null));

      Assert.IsTrue(ConvertUtils.ConvertOrCast<int?>(null) == new int?());
    }
    #endregion

    #region TryConvertOrCast
    [Test]
    public void TryConvertOrCastInt32()
    {
      int convertedValue;
      Assert.IsFalse(ConvertUtils.TryConvertOrCast<int>(string.Empty, out convertedValue));
      Assert.AreEqual(0, convertedValue);

      Assert.IsFalse(ConvertUtils.TryConvertOrCast<int>(DateTime.Now, out convertedValue));
      Assert.AreEqual(0, convertedValue);

      Assert.IsFalse(ConvertUtils.TryConvertOrCast<int>(null, out convertedValue));
      Assert.AreEqual(0, convertedValue);

      Assert.IsTrue(ConvertUtils.TryConvertOrCast<int>("9999", out convertedValue));
      Assert.AreEqual(9999, convertedValue);
    }
    #endregion
  }
}